package com.tressatisfiability.client;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DecoratorPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.tressatisfiability.shared.Formula;

public class Sat extends DecoratorPanel implements ClickHandler, KeyUpHandler {
	private ClientController controlador;
	private String s;
	private VerticalPanel panel;
	private ScrollPanel scroll;
	private HorizontalPanel paneltitulo;

	private VerticalPanel panel1;
	private TextArea textArea;
	private Button b;

	private VerticalPanel panel2;

	private VerticalPanel panel3;
	private Button reintentar;

	Sat(ClientController controlador) {
		this.controlador = controlador;
		panel = new VerticalPanel();
		scroll = new ScrollPanel(panel);
		paneltitulo = new HorizontalPanel();

		scroll.setSize("750px", "710px");
		panel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		panel.setVerticalAlignment(HasVerticalAlignment.ALIGN_TOP);
		panel.setSpacing(15);

		paneltitulo.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		paneltitulo.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
		paneltitulo.setWidth("700px");
		paneltitulo.setHeight("110px");
		paneltitulo.setStyleName("TittleCell");
		paneltitulo.add(new HTML("<H1>3 Satisfiability</H1>"));

		panel1 = new VerticalPanel();
		formatPanel(panel1);
		panel1.add(new HTML(
				"Pegue en el siguiente área de Texto la formula SAT3<div>Use el formato 'Conjunctive Normal Form'."));
		textArea = new TextArea();
		textArea.addKeyUpHandler(this);
		textArea.setWidth("544px");

		b = new Button("Satisfacer");
		b.addClickHandler(this);
		b.setEnabled(false);

		panel1.add(textArea);
		panel1.add(b);

		panel.add(paneltitulo);
		panel.add(panel1);

		setSize("750px", "610px");
		setWidget(scroll);
		setStyleName("Ventana");

	}

	@Override
	public void onClick(ClickEvent event) {
		if (event.getSource().equals(b)) {
			if (textArea.getText().length() > 0) {
				controlador.getServer().solve3Sat(textArea.getText().trim(),
						new AsyncCallback<Formula>() {

							@Override
							public void onFailure(Throwable caught) {
								caught.printStackTrace();
							}

							@Override
							public void onSuccess(Formula result) {
								mostrarResultados(result);
							}

						});
				panel2 = new VerticalPanel();
				formatPanel(panel2);
				panel3 = new VerticalPanel();
				formatPanel(panel3);
			}
		} else if (event.getSource().equals(reintentar)) {
			reintentar.setEnabled(false);
			controlador.getServer().retry(new AsyncCallback<Formula>() {

				@Override
				public void onFailure(Throwable caught) {
					caught.printStackTrace();
				}

				@Override
				public void onSuccess(Formula result) {
					panel.remove(panel3);
					panel.remove(panel2);
					panel2.clear();
					panel3 = new VerticalPanel();
					formatPanel(panel3);
					mostrarResultados(result);
					reintentar.setEnabled(true);
				}

			});
		}

	}

	private void formatPanel(HorizontalPanel p) {
		p.setSpacing(5);
		p.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		p.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
		p.setWidth("680px");
		p.setHeight("100px");
		p.setStyleName("Cell");
	}

	private void formatPanel(VerticalPanel p) {
		p.setSpacing(5);
		p.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER);
		p.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
		p.setWidth("680px");
		p.setHeight("100px");
		p.setStyleName("Cell");
	}

	private void prepareRestart() {
		reintentar = new Button("Retry");
		reintentar.addClickHandler(this);
	}

	private void mostrarResultados(Formula result) {
		panel2.add(new HTML("<H1>Formula</H1>"));
		panel2.add(new HTML(result.toString()));
		panel2.setWidth("680px");
		panel.add(panel2);
		panel3.setSpacing(10);
		if (result.isSatisfied()) {
			panel3.add(new HTML("<H1>Satisfied</H1>"));
			panel3.add(result.getVariablesHTML());
		} else {
			panel3.add(new HTML("<H1>Unsatisfied</H1>"));
			prepareRestart();
			panel3.add(reintentar);
		}

		panel3.setWidth("680px");
		panel.add(panel3);
	}

	@Override
	public void onKeyUp(KeyUpEvent event) {
		b.setEnabled(textArea.getText().length() > 0);
	}

}
